package com.guangaiboen.attendance.core.dispatcher.other.simplehttp;//package com.answern.claimv2.main.test.http;
//
//import org.apache.http.HttpEntityEnclosingRequest;
//import org.apache.http.HttpRequest;
//import org.apache.http.client.config.RequestConfig;
//import org.apache.http.client.protocol.HttpClientContext;
//import org.apache.http.impl.NoConnectionReuseStrategy;
//import org.apache.http.impl.client.CloseableHttpClient;
//import org.apache.http.impl.client.HttpClientBuilder;
//import org.apache.http.impl.client.HttpClients;
//import org.apache.http.pool.ConnPool;
//import org.springframework.beans.factory.config.AbstractFactoryBean;
//
//import javax.net.ssl.SSLException;
//import java.net.UnknownHostException;
//
///**
// * 简单封装Apache HC(HttpClient)
// * 可以把这个HttpClient理解为一个浏览器，使用时将请求都交给同一个浏览器执行，而不是每次新建一个浏览器
// */
//public class HttpClientFactoryBean extends AbstractFactoryBean<CloseableHttpClient> {
//
//    /**
//     * 最大连接数 - 所有路由对应的连接总数
//     */
//    private Integer maxConnTotal;
//    /**
//     * 单个路由（主机+端口做唯一标示）的最大连接数
//     */
//    private Integer maxConnPerRoute;
//
//    /**
//     * tcp 三次握手超时时间，该值在公网调用下会更有用（若在HTTP keep-alive/connection persistent下，仅在第一次连接才会握手）
//     */
//    private Integer connectTimeout;
//
//    /**
//     * 从连接池{@link ConnPool}内获取连接的等待超时时间，简单说就是连接池无空闲连接时获取的等待时间
//     */
//    private Integer connectionRequestTimeout;
//
//    /**
//     * socket timeout，可以粗略当作就是服务端响应超时时间
//     */
//    private Integer socketTimeout;
//
//    /**
//     * 重试次数
//     * 这里的重试只是针对IO类的，像逻辑错误码（报文返回的），http状态码非200的，不属于IO类错误，不会重试
//     * 这里列出几种会重试的情况
//     * 1. Socket timeout，可以简单的理解为服务端响应超时或网络超时
//     * 2. Socket closed 客户端socket已关闭
//     * 3. Connection reset 服务端socket已关闭或不存在
//     */
//    private Integer retryCount;
//
//    /**
//     * HTTP keep-alive
//     */
//    private boolean keepAlive;
//
//    @Override
//    protected void destroyInstance(CloseableHttpClient instance) throws Exception {
//        instance.close();
//    }
//
//    @Override
//    public Class<CloseableHttpClient> getObjectType() {
//        return CloseableHttpClient.class;
//    }
//
//    @Override
//    protected CloseableHttpClient createInstance() throws Exception {
//        RequestConfig requestConfig = RequestConfig.custom()
//                //socket timeout
//                .setSocketTimeout(socketTimeout)
//                //acquire timeout from connection pool
//                .setConnectionRequestTimeout(connectionRequestTimeout)
//                //tcp 3 way handshake timeout
//                .setConnectTimeout(connectTimeout)
//                .build();
//
//        HttpClientBuilder httpClientBuilder = HttpClients.custom()
//                .setMaxConnPerRoute(maxConnPerRoute)
//                .setMaxConnTotal(maxConnTotal)
//                .setDefaultRequestConfig(requestConfig);
//
//        if(retryCount > 0){
//            //Overwrite the default retry handler to support so_timeout retry
//            httpClientBuilder.setRetryHandler((exception, executionCount, context) -> {
//                if (executionCount >= retryCount) {
//                    // Do not retry if over max retry count
//                    return false;
//                }
//                if (exception instanceof UnknownHostException) {
//                    // Unknown host
//                    return false;
//                }
//                if (exception instanceof SSLException) {
//                    // SSL handshake exception
//                    return false;
//                }
//                HttpClientContext clientContext = HttpClientContext.adapt(context);
//                HttpRequest request = clientContext.getRequest();
//                boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
//                if (idempotent) {
//                    // Retry if the request is considered idempotent
//                    return true;
//                }
//                return false;
//            });
//        }
//        if(!keepAlive) {
//            httpClientBuilder.setConnectionReuseStrategy(NoConnectionReuseStrategy.INSTANCE);
//        }
//
//        return httpClientBuilder.build();
//    }
//
//    public void setMaxConnTotal(Integer maxConnTotal) {
//        this.maxConnTotal = maxConnTotal;
//    }
//
//    public void setMaxConnPerRoute(Integer maxConnPerRoute) {
//        this.maxConnPerRoute = maxConnPerRoute;
//    }
//
//    public void setConnectTimeout(Integer connectTimeout) {
//        this.connectTimeout = connectTimeout;
//    }
//
//    public void setConnectionRequestTimeout(Integer connectionRequestTimeout) {
//        this.connectionRequestTimeout = connectionRequestTimeout;
//    }
//
//    public void setSocketTimeout(Integer socketTimeout) {
//        this.socketTimeout = socketTimeout;
//    }
//
//    public void setRetryCount(Integer retryCount) {
//        this.retryCount = retryCount;
//    }
//
//    public void setKeepAlive(boolean keepAlive) {
//        this.keepAlive = keepAlive;
//    }
//}
